import random

from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.conf import settings
from django_redis import get_redis_connection

from utils.bookstrap import *
from utils.md5 import md5
from utils.tencent.sms import send_sms_single
from web.models import UserInfo


class UserInfoModelForm(BookStrapModelForm):
    mobile_phone = forms.CharField(label='手机号',
                                   validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误'), ])
    password = forms.CharField(
        label='密码',
        min_length=8,
        max_length=64,
        error_messages={
            'min_length': '密码长度不能小于8位！',
            'max_length': '密码长度不能大于64位！',
        },
        widget=forms.PasswordInput()
    )
    confirm_password = forms.CharField(label='重复密码', widget=forms.PasswordInput())
    code = forms.CharField(
        label='验证码',
        widget=forms.TextInput())

    class Meta:
        model = UserInfo
        fields = ['user_name', 'mail', 'password', 'confirm_password', 'mobile_phone', 'code']

    def clean_password(self):
        pwd = self.cleaned_data.get('password')
        return md5(pwd)

    def clean_confirm_password(self):
        pwd = self.cleaned_data.get('password')
        c_pwd = self.cleaned_data.get('confirm_password')
        if pwd != md5(c_pwd):
            raise ValidationError('重复密码不一致！')
        return md5(c_pwd)

    def clean_mail(self):
        mail_address = self.cleaned_data.get('mail')
        exists = UserInfo.objects.filter(mail=mail_address).exists()
        if exists:
            raise ValidationError('此邮箱已注册')
        return mail_address

    def clean_mobile_phone(self):
        mobile_phone = self.cleaned_data.get('mobile_phone')
        exists = UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if exists:
            raise ValidationError('此手机已注册')
        return mobile_phone

    def clean_code(self):
        code = self.cleaned_data.get('code')
        conn = get_redis_connection('default')
        mobile_phone = self.cleaned_data.get('mobile_phone')
        code_radis = conn.get(mobile_phone)
        if not code_radis:
            raise ValidationError('请点击获取验证码！')
        # code_radis是bytes类型，用decode的转为str类型
        code_radis_str = code_radis.decode('utf-8')
        # strip 去掉首尾两端的空格
        if code.strip() != code_radis_str.strip():
            raise ValidationError('输入的验证码不对，请重新输入！')
        return code


class SendSmsForm(forms.Form):
    mobile_phone = forms.CharField(label='手机号',
                                   validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误'), ])

    def __init__(self, request, *args, **kwargs):
        """ 重写构造函数，将request传进来 """
        super().__init__(*args, **kwargs)
        self.request = request

    def clean_mobile_phone(self):
        """ 验证手机号的勾子方法 """
        mobile_phone = self.cleaned_data.get("mobile_phone")
        # 验证短信发送使用的短信模板是否正确
        frl = self.request.POST.get('frl')
        template_id = settings.TENCENT_SMS_TEMPLATE.get(frl)
        if not template_id:
            raise ValidationError("短信模板不正确！")
        # 验证手机号是否已存在，已注册过了
        exists = UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if exists:
            raise ValidationError("手机号已存在！")
        # 发短信
        code = random.randrange(1000, 9999)
        # sms = send_sms_single(mobile_phone, template_id, [code, ])
        # if sms.get('result') != 0:
        #     raise ValidationError("短信发送失败，{}".format(sms.get('errmsg')))
        # 验证码写入redis
        conn = get_redis_connection('default')
        conn.set(mobile_phone, code, ex=settings.COUNT_DOWN_SECONDS)
        return mobile_phone


class LoginSmsForm(BookStrapForm):
    mobile_phone = forms.CharField(
        label='手机号',
        validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误'), ]
    )

    code = forms.CharField(
        label='验证码',
        widget=forms.TextInput())
